#pragma once

#include <AVUIRangeBase.h>

namespace AVUI {
class Track;
class RoutedEventArgs;
class DragDeltaEventArgs;
class Slider : public RangeBase
{
public:
    Slider() : m_pTrack(NULL) { };
    ~Slider() { };

    DECLARE_ELEMENT(Slider, RangeBase);

    DECLARE_DEPENDENCY_PROPERTY(Orientation);
    Orientation::Enum get_Orientation() { return (Orientation::Enum)(AVUI::UnboxValue<int>(GetValue(get_OrientationProperty()))); }
    void set_Orientation(Orientation::Enum value) { SetValue(get_OrientationProperty(), AVUI::BoxValue<int>(value)); } 

    DECLARE_DEPENDENCY_PROPERTY(IsDirectionReversed);
    bool get_IsDirectionReversed() { return AVUI::UnboxValue<bool>(GetValue(get_IsDirectionReversedProperty())); }
    void set_IsDirectionReversed(bool value) { SetValue(get_IsDirectionReversedProperty(), AVUI::BoxValue(value)); } 

    DECLARE_DEPENDENCY_PROPERTY(IsSnapToTickEnabled);
    bool get_IsSnapToTickEnabled() { return AVUI::UnboxValue<bool>(GetValue(get_IsSnapToTickEnabledProperty())); }
    void set_IsSnapToTickEnabled(bool value) { SetValue(get_IsSnapToTickEnabledProperty(), AVUI::BoxValue(value)); } 

    DECLARE_DEPENDENCY_PROPERTY(TickFrequency);
    float get_TickFrequency() { return AVUI::UnboxValue<float>(GetValue(get_TickFrequencyProperty())); }
    void set_TickFrequency(float value) { SetValue(get_TickFrequencyProperty(), AVUI::BoxValue(value)); } 

    DECLARE_DEPENDENCY_PROPERTY(TickPlacement);
    TickPlacement::Enum get_TickPlacement() { return (TickPlacement::Enum)(AVUI::UnboxValue<int>(GetValue(get_TickPlacementProperty()))); }
    void set_TickPlacement(TickPlacement::Enum value) { SetValue(get_TickPlacementProperty(), AVUI::BoxValue<int>(value)); } 

    IMPLEMENT_ROUTED_COMMAND(IncreaseLarge);
    IMPLEMENT_ROUTED_COMMAND(DecreaseLarge);
    IMPLEMENT_ROUTED_COMMAND(IncreaseSmall);
    IMPLEMENT_ROUTED_COMMAND(DecreaseSmall);
    IMPLEMENT_ROUTED_COMMAND(MinimizeValue);
    IMPLEMENT_ROUTED_COMMAND(MaximizeValue);

protected:
    virtual void OnApplyTemplate();

    virtual void OnIncreaseLarge();
    virtual void OnDecreaseLarge();
    virtual void OnIncreaseSmall();
    virtual void OnDecreaseSmall();
    virtual void OnMinimizeValue();
    virtual void OnMaximizeValue();

    virtual void OnKeyDown(KeyEventArgs* pArgs) AVUI_OVERRIDE;

private:
    static void StaticConstructor();
    static void _OnMouseLeftButtonDown(Object* pSender, MouseButtonEventArgs* e);

    void MoveToNextTick(float direction);

    float SnapToTick(float value);
    void UpdateValue(float newValue);
    void ChangeValue(float newValue);

    void OnDragStarted(RoutedEventArgs* pArgs);
    void OnDragDelta(DragDeltaEventArgs* pArgs);
    void OnDragCompleted(RoutedEventArgs* pArgs);

    static void OnDragStartedThunk(Object* pSender, RoutedEventArgs* pArgs) { ((Slider*) pSender)->OnDragStarted(pArgs); }
    static void OnDragDeltaThunk(Object* pSender, DragDeltaEventArgs* pArgs) { ((Slider*) pSender)->OnDragDelta((DragDeltaEventArgs*)pArgs); }
    static void OnDragCompletedThunk(Object* pSender, RoutedEventArgs* pArgs) { ((Slider*) pSender)->OnDragCompleted(pArgs); }
    static void OnIncreaseLargeCommand(Object* pSender, ExecutedRoutedEventArgs* pArgs);
    static void OnDecreaseLargeCommand(Object* pSender, ExecutedRoutedEventArgs* pArgs);
    static void OnIncreaseSmallCommand(Object* pSender, ExecutedRoutedEventArgs* pArgs);
    static void OnDecreaseSmallCommand(Object* pSender, ExecutedRoutedEventArgs* pArgs);
    static void OnMinimizeValueCommand(Object* pSender, ExecutedRoutedEventArgs* pArgs);
    static void OnMaximizeValueCommand(Object* pSender, ExecutedRoutedEventArgs* pArgs);

    Track* m_pTrack;
};


}; // namespace AVUI


